package rgbos.forum.webClient;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Vector;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

import rgbos.forum.domain.Auditor;
import rgbos.forum.domain.Post;
import rgbos.forum.domain.Topic;
import rgbos.forum.domain.User;
import rgbos.forum.exceptions.HashException;
import rgbos.forum.serverClient.Forum;
import jaxcent.HtmlDiv;
import jaxcent.HtmlImage;
import jaxcent.HtmlInputButton;
import jaxcent.HtmlInputText;
import jaxcent.HtmlPara;
import jaxcent.HtmlSelect;
import jaxcent.HtmlTable;
import jaxcent.JaxcentPage;
import jaxcent.Jaxception;

public class ShowProfile extends jaxcent.JaxcentPage {

	HtmlPara para_ = new HtmlPara(this,"header");
	HtmlPara footpara_ = new HtmlPara(this,"footerPara");
	HtmlDiv loading = new HtmlDiv(this, "loading");
	HtmlDiv statistics = new HtmlDiv(this, "statistics");
	DateFormat df_ = new SimpleDateFormat("dd/MM/yyyy");
	WebClientHandler handler_ = WebClientHandler.getWebClientHandler();;
	User user_;
	private Vector<String> usernames_;
	private String picturesPath= Forum.htmlPath;
	private int count=0;
	public ShowProfile() {
		super();
		this.setFormSaveEnabled(false);
	}
	
	protected void onUnload() {
		try {
			Map sessionData = getAllSessionData(false);
			handler_.unload(sessionData);			
		} catch (Jaxception e) {
			e.printStackTrace();
		}
	}

	protected void onLoad() {
		try {			
			Map sessionData = getAllSessionData( false );
			handler_.DisplayHeader(para_, sessionData, this); //must be before display footer!
			handler_.displayFooter(footpara_, sessionData, this);
			String permissions = handler_.getClientType(sessionData);
			if (permissions.equals("Guest")) {
				showMessageDialog("Can't edit a guest profile. Please log in and try again");
				navigate( "/showTopics.html" );
				return;
			}
			user_ = handler_.getControl().getUserByName((String)sessionData.get("uName"));
			if (user_ != null) {
				HtmlDiv username = new HtmlDiv(this, "Username");
				username.setInnerHTML(user_.getUsername());
				HtmlInputText email = new HtmlInputText(this, "Email");
				email.setValue(user_.getEmail());
			}
			final JaxcentPage page = this;

			HtmlInputButton update = new HtmlInputButton(this, "changeProfileButton") {
				protected void onClick( Map pageData ) {
					String oldPassword = (String) pageData.get("OldPassword");
					String pass1 = (String) pageData.get("Password");
					String pass2 = (String) pageData.get("Password2");
					String email = (String) pageData.get("Email");
					try {
						String hashedOldPass = handler_.hashString(oldPassword);
						String hashPass = handler_.hashString(pass1);
						if(pass1.length()>10){
							showMessageDialog("New Password needs to be 10 chars max");
						}else if(!isValidEmailAddress(email)){
							showMessageDialog("The email address is not valid");
						}else if(!oldPassword.equals("") && !pass1.equals(pass2)){
							showMessageDialog("Passwords doesn't match");
						}else if(!oldPassword.equals("") && !hashedOldPass.equals(user_.getPassword())){
							showMessageDialog("Old password is not correct");
						}else if(!handler_.isLegal(pass1)){
							showMessageDialog("Your password contains illegal characters. Please remove them and try again");
						}else{
							if (oldPassword.equals("")) {
								User user = new User(user_.getUsername(), user_.getPassword(), email, user_.getPermmisionGroup());
								if (!handler_.getControl().modifyUser(user)) {
									showMessageDialog("Can't update profile. Please refresh the page and try again.");
								}
								else {
									page.navigate( "/showTopics.html" );
								}
							}
							else {
								User user = new User(user_.getUsername(), hashPass, email, user_.getPermmisionGroup());
								if (!handler_.getControl().modifyUser(user)) {
									showMessageDialog("Can't update profile. Please refresh the page and try again.");
								}
								else {
									page.navigate( "/showTopics.html" );
								}
							}
						}
					} catch (HashException e1) {
						showMessageDialog("Can't update profile. Please refresh the page and try again.");
					} catch (Jaxception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			};

			update.setValue("Update Profile");

			HtmlInputButton cancel = new HtmlInputButton(this, "cancelProfileButton") {
				protected void onClick( Map pageData ) {
					try {
						page.goBack();
					} catch (Jaxception e) {
						try {
							navigate( "/showTopics.html" );
						} catch (Jaxception e1) {
							e1.printStackTrace();
						}
					}
				}
			};
			cancel.setValue("Cancel");
			this.usernames_ = handler_.getControl().getAllUsersName();
			Collections.sort(usernames_);
			if(permissions.contentEquals("Admin")){
				HtmlTable table = new HtmlTable(this, "ModTable");
				table.setStyle("visibility", "visible");
				HtmlSelect userToModSel =new HtmlSelect(page,"userForModSel"){
					protected void onChange(String value){
						try {
							if(!showConfirmDialog("Are you sure you want "+value+" to be a moderator?")){
								return;
							}
						} catch (Jaxception e) {
							e.printStackTrace();
						}
						if(handler_.getControl().turnToMod(value)){
							showMessageDialog("Success, "+value+" is now moderator.");
						}else{
							showMessageDialog("Error, "+value+" is not a moderator.");
						}
					}
				};
				for(int i=0; i<this.usernames_.size();i++){
					userToModSel.insertOption(i,usernames_.elementAt(i));
					if (usernames_.elementAt(i).equals(user_.getUsername()))
						userToModSel.setSelectedIndex(i);
				}
				
				HtmlSelect delUser = new HtmlSelect(page,"delUser"){
					protected void onChange(String value){
						try {
							if(!showConfirmDialog("Are you sure you want to delete the user "+value+" from the forum?")){
								return;
							}
						} catch (Jaxception e) {
							e.printStackTrace();
						}
						if(handler_.getControl().deleteUser(value)){
							showMessageDialog("Success, you deleted "+value+" from the forum");
						}else{
							showMessageDialog("Error, "+value+" could not be deleted from the forum");
						}
					}
				};
				for(int i=0; i<this.usernames_.size();i++){
					delUser.insertOption(i,usernames_.elementAt(i));
					if (usernames_.elementAt(i).equals(user_.getUsername()))
						delUser.setSelectedIndex(i);
				}
			}
			if (permissions.contentEquals("Moderator") | permissions.contentEquals("Admin")) {
				loading.setStyle("display", "block");
				HtmlTable table = new HtmlTable(this, "StatsStable");
				table.setStyle("visibility", "visible");
				String filename = getOneUserChart((String)sessionData.get("uName"), Calendar.getInstance().getTime());
				final HtmlImage chart1 = new HtmlImage(this, "chart1");
				chart1.setSrc(filename);
				HtmlSelect userStats =new HtmlSelect(page,"getStatSel"){
					protected void onChange(String value){
						String filename;
						try {
							filename = getOneUserChart(value, Calendar.getInstance().getTime());
							chart1.setSrc(filename);
						} catch (Jaxception e) {
							Auditor.Log(e.getMessage(), this.getClass());
						}
					}
				};
				for(int i=0; i<this.usernames_.size();i++){
					userStats.insertOption(i,this.usernames_.elementAt(i));
					if (usernames_.elementAt(i).equals(user_.getUsername()))
						userStats.setSelectedIndex(i);
				}
				String hoursChartFileName = getPostByHoursGraph();
				final HtmlImage hourchart = new HtmlImage(this, "chart2");
				hourchart.setSrc(hoursChartFileName);
				String usersHoursChartFileName = getUsresByHoursGraph();
				final HtmlImage usersHourchart = new HtmlImage(this, "chart3");
				usersHourchart.setSrc(usersHoursChartFileName);
				loading.setStyle("display", "none");
				statistics.setStyle("display", "block");
			}
			
			
		} catch (Jaxception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private String getPostByHoursGraph() {
        Vector<Topic> topics = handler_.getControl().getAllTopics();
        Vector<Post> posts =new Vector<Post>();
        for (int i = 0; i < topics.size(); i++) {
			Vector<Integer> p = topics.elementAt(i).getPostVector();
			for (Integer integer : p) {
				posts.add(handler_.getControl().getPostById(integer));
			}
		}
        if (posts == null || posts.size() == 0) {
        	return "noImage.jpg";
        }
        int[] postsForHour = new int[24];
        for (Post post : posts) {
        	System.out.println(post.getCreationDate_());
        	int hour = post.getCreationDate_().getHours();
			postsForHour[hour]++;
		}
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (int i = 0; i < postsForHour.length; i++) {
        	dataset.addValue((Number)postsForHour[i], "Hour", i+1);
		}
        JFreeChart chart = ChartFactory.createBarChart("Number of messages sorted by creation hour",
                "Hour", "Number of Messages", dataset, PlotOrientation.VERTICAL, false,
                true, false);
        try {
            count++;
            ChartUtilities.saveChartAsJPEG(new File(picturesPath+"hourchart"+String.valueOf(count)+".jpg"), chart, 800,
                300);
            return "hourchart"+String.valueOf(count)+".jpg";
        } catch (IOException e) {
            Auditor.Log("Problem occurred creating chart.",this.getClass());
        }
        return "noImage.jpg";
	}
	private String getUsresByHoursGraph() {
        int[] usersForHours = handler_.getControl().getHourStats();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (int i = 0; i < usersForHours.length; i++) {
        	dataset.addValue((Number)usersForHours[i], "Hour", i+1);
		}
        JFreeChart chart = ChartFactory.createBarChart("Number of Online Users sorted by hour",
                "Hour", "Number of Users", dataset, PlotOrientation.VERTICAL, false,
                true, false);
        try {
            count++;
            ChartUtilities.saveChartAsJPEG(new File(picturesPath+"usershourchart"+String.valueOf(count)+".jpg"), chart, 800,
                300);
            return "usershourchart"+String.valueOf(count)+".jpg";
        } catch (IOException e) {
            Auditor.Log("Problem occurred creating chart.",this.getClass());
        }
        return "noImage.jpg";
	}
	private String getOneUserChart(String username, Date date) {

        Vector<Post> posts = handler_.getControl().getPostsByUser(username);
        if (posts == null || posts.size() == 0) {
        	return "noImage.jpg";
        }
        int numOfDays = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
        int[] postsForDay = new int[numOfDays];

        DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
        for (Post post : posts) {
        	df = new SimpleDateFormat("dd");
			int day = Integer.valueOf(df.format(post.getCreationDate_()));
			df = new SimpleDateFormat("MM");
			if (df.format(post.getCreationDate_()).contentEquals(df.format(date)) &&
				day <= postsForDay.length) {
				postsForDay[day-1]++;
			}

		}

        String[] monthName = {"January", "February",
        						"March", "April", "May", "June", "July",
        						"August", "September", "October", "November",
        						"December"};

        df = new SimpleDateFormat("MM");
		String month = monthName[Integer.valueOf(df.format(date))-1];

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (int i = 0; i < postsForDay.length; i++) {
        	dataset.addValue((Number)postsForDay[i], "Days", i+1);
		}
        JFreeChart chart = ChartFactory.createBarChart("Number of messages for User " + username + " in " + month,
                "Days", "Number of Messages", dataset, PlotOrientation.VERTICAL, false,
                true, false);
        try {
            count++;
            ChartUtilities.saveChartAsJPEG(new File(picturesPath+"chart"+String.valueOf(count)+".jpg"), chart, 800,
                300);
            return "chart"+String.valueOf(count)+".jpg";
        } catch (IOException e) {
            Auditor.Log("Problem occurred creating chart.",this.getClass());
        }
        return "noImage.jpg";
	}

	public  boolean isValidEmailAddress(String aEmailAddress){
	    if (aEmailAddress == null) return false;
	    boolean result = true;
	    String[] tokens = aEmailAddress.split("@");
	     if (aEmailAddress.startsWith(".") || aEmailAddress.startsWith("@") || tokens.length!=2 || tokens[1].startsWith(".") || !tokens[1].contains(".")) {
	        result = false;
	      }
	    return result;
	}
}

